#ifndef DATABASE_MIGRATION_0_H
#define DATABASE_MIGRATION_0_H

#include "migration.hpp"

namespace Database
{

class M0000001 final : public Migration
{
public:
    virtual void up(sqlite::database& database) override
    {
        // Рабочий процесс -----------------------------------------------------
        database << "CREATE TABLE Workflow"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    // Поля с данными
                    ", caption VARCHAR"
                    ", description VARCHAR"
                    ");";

        database << "CREATE TABLE State"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", workflowId INTEGER"
                    // Поля с данными
                    ", caption VARCHAR"
                    ", description VARCHAR"
                    ", weight INTEGER"
                    ", orderNumber INTEGER"
                    ", isArchive BOOLEAN"
                    ", isQueue BOOLEAN"
                    // Отношения
                    ", FOREIGN KEY(workflowId) REFERENCES Workflow(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexStateWorkflow ON State(workflowId)";

        database << "CREATE TABLE Edge"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", beginStateId INTEGER"
                    ", endStateId INTEGER"
                    // Отношения
                    ", FOREIGN KEY(beginStateId) REFERENCES State(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(endStateId) REFERENCES State(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexEdgeBeginState ON Edge(beginStateId)";
        database << "CREATE INDEX IndexEdgeEndState ON Edge(endStateId)";

        // Проект --------------------------------------------------------------
        database << "CREATE TABLE Project"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", parentId INTEGER"
                    // Поля с данными
                    ", caption VARCHAR"
                    ", description VARCHAR"
                    // Доп поля поиска
                    ", searchCaption VARCHAR"
                    ", searchDescription VARCHAR"
                    // Отношения
                    ", FOREIGN KEY(parentId) REFERENCES Project(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexProjectParent ON Project(parentId)";

        database << "CREATE TABLE Phase"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", projectId INTEGER"
                    // Поля с данными
                    ", caption VARCHAR"
                    ", description VARCHAR"
                    ", beginDate DATE"
                    ", endDate DATE"
                    // Доп поля поиска
                    ", searchCaption VARCHAR"
                    ", searchDescription VARCHAR"
                    // Отношения
                    ", FOREIGN KEY(projectId) REFERENCES Project(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexPhaseProject ON Phase(projectId)";

        // Доска ---------------------------------------------------------------
        database << "CREATE TABLE Board"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", workflowId INTEGER"
                    ", projectId INTEGER"
                    ", phaseId INTEGER"
                    // Поля с данными
                    ", caption VARCHAR"
                    ", description VARCHAR"
                    // Отношения
                    ", FOREIGN KEY(workflowId) REFERENCES Workflow(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(projectId) REFERENCES Project(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(phaseId) REFERENCES Phase(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexBoardWorkflow ON Board(workflowId)";
        database << "CREATE INDEX IndexBoardProject ON Board(projectId)";
        database << "CREATE INDEX IndexBoardPhase ON Board(phaseId)";

        database << "CREATE TABLE BoardColumn"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", boardId INTEGER"
                    ", stateId INTEGER"
                    // Поля с данными
                    ", orderNumber INTEGER"
                    // Отношения
                    ", FOREIGN KEY(boardId) REFERENCES Board(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(stateId) REFERENCES State(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexBoardColumnBoard ON BoardColumn(boardId)";
        database << "CREATE INDEX IndexBoardColumnState ON BoardColumn(stateId)";

        // Пользователь --------------------------------------------------------
        database << "CREATE TABLE User"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    // Поля с данными
                    ", login VARCHAR"
                    ", firstName VARCHAR"
                    ", middleName VARCHAR"
                    ", lastName VARCHAR"
                    ", email VARCHAR"
                    ", passwordHash VARCHAR"
                    ", needChangePassword BOOLEAN"
                    ", isBlocked BOOLEAN"
                    ", uiLang VARCHAR"
                    ");";

        database << "CREATE TABLE Team"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    // Поля с данными
                    ", caption VARCHAR"
                    ", description VARCHAR"
                    ");";

        database << "CREATE TABLE Role"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    // Поля с данными
                    ", caption VARCHAR"
                    ", description VARCHAR"
                    ", basePermissions INTEGER"
                    ");";

        database << "CREATE TABLE UserTeamRole"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", userId INTEGER"
                    ", teamId INTEGER"
                    ", roleId INTEGER"
                    // Отношения
                    ", FOREIGN KEY(userId) REFERENCES User(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(teamId) REFERENCES Team(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(roleId) REFERENCES Role(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexUserTeamRoleUser ON UserTeamRole(userId)";
        database << "CREATE INDEX IndexUserTeamRoleTeam ON UserTeamRole(teamId)";
        database << "CREATE INDEX IndexUserTeamRoleRole ON UserTeamRole(roleId)";

        database << "CREATE TABLE RoleMenuItem"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", roleId INTEGER"
                    // Поля с данными
                    ", caption VARCHAR"
                    ", link VARCHAR"
                    ", icon VARCHAR"
                    // Отношения
                    ", FOREIGN KEY(roleId) REFERENCES Role(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexRoleMenuItemRole ON RoleMenuItem(roleId)";

        database << "CREATE TABLE ProjectTeam"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", projectId INTEGER"
                    ", teamId INTEGER"
                    // Отношения
                    ", FOREIGN KEY(projectId) REFERENCES Project(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(teamId) REFERENCES Team(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexProjectTeamProject ON ProjectTeam(projectId)";
        database << "CREATE INDEX IndexProjectTeamTeam ON ProjectTeam(teamId)";

        // Документ ------------------------------------------------------------
        database << "CREATE TABLE Document"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    // Поля с данными
                    ", caption VARCHAR"
                    ", description VARCHAR"
                    // Доп поля поиска
                    ", searchCaption VARCHAR"
                    ", searchDescription VARCHAR"
                    ");";

        database << "CREATE TABLE DocumentVersion"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", documentId INTEGER"
                    // Поля с данными
                    ", filename VARCHAR"
                    ", path VARCHAR"
                    // Отношения
                    ", FOREIGN KEY(documentId) REFERENCES Document(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexDocumentVersionDocument ON DocumentVersion(documentId)";

        // Сообщение -----------------------------------------------------------
        database << "CREATE TABLE PrivateMessage"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", senderUserId INTEGER"
                    ", receiverUserId INTEGER"
                    // Поля с данными
                    ", creationTimestamp DATETIME"
                    ", content VARCHAR"
                    ", isViewed BOOLEAN"
                    // Отношения
                    ", FOREIGN KEY(senderUserId) REFERENCES User(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(receiverUserId) REFERENCES User(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexPrivateMessageSenderUser ON PrivateMessage(senderUserId)";
        database << "CREATE INDEX IndexPrivateMessageReceiverUser ON PrivateMessage(receiverUserId)";

        database << "CREATE TABLE TeamMessage"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", senderUserId INTEGER"
                    ", teamId INTEGER"
                    // Поля с данными
                    ", creationTimestamp DATETIME"
                    ", content VARCHAR"
                    // Отношения
                    ", FOREIGN KEY(senderUserId) REFERENCES User(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(teamId) REFERENCES Team(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexTeamMessageSenderUser ON TeamMessage(senderUserId)";
        database << "CREATE INDEX IndexTeamMessageTeam ON TeamMessage(teamId)";

        // Объект предметной области -------------------------------------------
        database << "CREATE TABLE ItemType"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", workflowId INTEGER"
                    ", defaultStateId INTEGER"
                    // Поля с данными
                    ", caption VARCHAR"
                    ", kind INTEGER"
                    // Отношения
                    ", FOREIGN KEY(workflowId) REFERENCES Workflow(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(defaultStateId) REFERENCES State(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexItemTypeWorkflow ON ItemType(workflowId)";
        database << "CREATE INDEX IndexItemTypeState ON ItemType(defaultStateId)";

        database << "CREATE TABLE Item"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", itemTypeId INTEGER"
                    ", parentId INTEGER"
                    ", stateId INTEGER"
                    ", phaseId INTEGER"
                    // Поля с данными
                    ", caption VARCHAR"
                    ", description VARCHAR"
                    // Доп поля поиска
                    ", searchCaption VARCHAR"
                    ", searchDescription VARCHAR"
                    // Отношения
                    ", FOREIGN KEY(itemTypeId) REFERENCES ItemType(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(parentId) REFERENCES Item(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(stateId) REFERENCES State(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(phaseId) REFERENCES Phase(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexItemItemType ON Item(itemTypeId)";
        database << "CREATE INDEX IndexItemParent ON Item(parentId)";
        database << "CREATE INDEX IndexItemState ON Item(stateId)";
        database << "CREATE INDEX IndexItemPhase ON Item(phaseId)";

        database << "CREATE TABLE FieldType"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", itemTypeId INTEGER"
                    // Поля с данными
                    ", caption VARCHAR"
                    ", description VARCHAR"
                    ", valueType INTEGER"
                    ", isBoardVisible BOOLEAN"
                    // Отношения
                    ", FOREIGN KEY(itemTypeId) REFERENCES ItemType(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexFieldTypeItemType ON FieldType(itemTypeId)";

        database << "CREATE TABLE FieldTypePossibleValue"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", fieldTypeId INTEGER"
                    // Поля с данными
                    ", value VARCHAR"
                    // Отношения
                    ", FOREIGN KEY(fieldTypeId) REFERENCES FieldType(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexFieldTypePossibleValueFieldType ON FieldTypePossibleValue(fieldTypeId)";

        database << "CREATE TABLE ItemField"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", itemId INTEGER"
                    ", fieldTypeId INTEGER"
                    // Поля с данными
                    ", value VARCHAR"
                    // Доп поля поиска
                    ", searchValue VARCHAR"
                    // Отношения
                    ", FOREIGN KEY(itemId) REFERENCES Item(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(fieldTypeId) REFERENCES FieldType(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexItemFieldItem ON ItemField(itemId)";
        database << "CREATE INDEX IndexItemFieldFieldType ON ItemField(fieldTypeId)";

        database << "CREATE TABLE LinkType"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", sourceItemTypeId INTEGER"
                    ", destinationItemTypeId INTEGER"
                    // Поля с данными
                    ", isBidirectional BOOLEAN"
                    ", caption VARCHAR"
                    // Отношения
                    ", FOREIGN KEY(sourceItemTypeId) REFERENCES ItemType(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(destinationItemTypeId) REFERENCES ItemType(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexLinkTypeSourceItemType ON LinkType(sourceItemTypeId)";
        database << "CREATE INDEX IndexLinkTypeDestinaionItemType ON LinkType(destinationItemTypeId)";

        database << "CREATE TABLE ItemLink"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", linkTypeId INTEGER"
                    ", sourceItemId INTEGER"
                    ", destinationItemId INTEGER"
                    // Отношения
                    ", FOREIGN KEY(linkTypeId) REFERENCES LinkType(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(sourceItemId) REFERENCES Item(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(destinationItemId) REFERENCES Item(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexItemLinkLinkType ON ItemLink(linkTypeId)";
        database << "CREATE INDEX IndexItemLinkSourceItem ON ItemLink(sourceItemId)";
        database << "CREATE INDEX IndexItemLinkDestinaionItem ON ItemLink(destinationItemId)";

        database << "CREATE TABLE ItemPlan"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", itemId INTEGER"
                    ", userId INTEGER"
                    // Поля с данными
                    ", timestamp DATETIME"
                    ", duration TIME"
                    // Отношения
                    ", FOREIGN KEY(itemId) REFERENCES Item(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(userId) REFERENCES User(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexItemPlanItem ON ItemPlan(itemId)";
        database << "CREATE INDEX IndexItemPlanUser ON ItemPlan(userId)";

        database << "CREATE TABLE ItemHistory"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", itemId INTEGER"
                    ", userId INTEGER"
                    // Поля с данными
                    ", timestamp DATETIME"
                    ", diff VARCHAR"
                    // Отношения
                    ", FOREIGN KEY(itemId) REFERENCES Item(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(userId) REFERENCES User(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexItemHistoryItem ON ItemHistory(itemId)";
        database << "CREATE INDEX IndexItemHistoryUser ON ItemHistory(userId)";

        database << "CREATE TABLE ItemUserState"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", itemId INTEGER"
                    ", userId INTEGER"
                    ", stateId INTEGER"
                    // Поля с данными
                    ", timestamp DATETIME"
                    // Отношения
                    ", FOREIGN KEY(itemId) REFERENCES Item(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(userId) REFERENCES User(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(stateId) REFERENCES State(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexItemUserStateItem ON ItemUserState(itemId)";
        database << "CREATE INDEX IndexItemUserStateUser ON ItemUserState(userId)";
        database << "CREATE INDEX IndexItemUserStateState ON ItemUserState(stateId)";

        database << "CREATE TABLE ItemDocumentVersion"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", itemId INTEGER"
                    ", documentVersionId INTEGER"
                    // Отношения
                    ", FOREIGN KEY(itemId) REFERENCES Item(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(documentVersionId) REFERENCES DocumentVersion(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexItemDocumentVersionItem ON ItemDocumentVersion(itemId)";
        database << "CREATE INDEX IndexItemDocumentVersionDocumentVersion ON ItemDocumentVersion(documentVersionId)";

        // Комментарий ---------------------------------------------------------
        database << "CREATE TABLE Comment"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", userId INTEGER"
                    ", itemId INTEGER"
                    // Поля с данными
                    ", creationTimestamp DATETIME"
                    ", content VARCHAR"
                    // Доп поля поиска
                    ", searchContent VARCHAR"
                    // Отношения
                    ", FOREIGN KEY(userId) REFERENCES User(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(itemId) REFERENCES Item(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexCommentUser ON Comment(userId)";
        database << "CREATE INDEX IndexCommentItem ON Comment(itemId)";

        database << "CREATE TABLE CommentDocumentVersion"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", commentId INTEGER"
                    ", documentVersionId INTEGER"
                    // Отношения
                    ", FOREIGN KEY(commentId) REFERENCES Comment(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(documentVersionId) REFERENCES DocumentVersion(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexCommentDocumentVersionComment ON CommentDocumentVersion(commentId)";
        database << "CREATE INDEX IndexCommentDocumentVersionDocumentVersion ON CommentDocumentVersion(documentVersionId)";

        // Права и правила -----------------------------------------------------
        database << "CREATE TABLE Rule"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", roleId INTEGER"
                    // Отношения
                    ", FOREIGN KEY(roleId) REFERENCES Role(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexRuleRole ON RoleMenuItem(roleId)";

        database << "CREATE TABLE RuleState"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", ruleId INTEGER"
                    ", stateId INTEGER"
                    // Поля с данными
                    ", permissions INTEGER"
                    // Отношения
                    ", FOREIGN KEY(ruleId) REFERENCES Rule(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(stateId) REFERENCES State(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexRuleStateRole ON RuleState(ruleId)";
        database << "CREATE INDEX IndexRuleStateState ON RuleState(stateId)";

        database << "CREATE TABLE RuleItemType"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", ruleId INTEGER"
                    ", itemTypeId INTEGER"
                    // Поля с данными
                    ", permissions INTEGER"
                    // Отношения
                    ", FOREIGN KEY(ruleId) REFERENCES Rule(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(itemTypeId) REFERENCES ItemType(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexRuleItemTypeRole ON RuleItemType(ruleId)";
        database << "CREATE INDEX IndexRuleItemTypeItemType ON RuleItemType(itemTypeId)";

        database << "CREATE TABLE RuleProject"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", ruleId INTEGER"
                    ", projectId INTEGER"
                    // Поля с данными
                    ", permissions INTEGER"
                    // Отношения
                    ", FOREIGN KEY(ruleId) REFERENCES Rule(id) ON DELETE CASCADE"
                    ", FOREIGN KEY(projectId) REFERENCES Project(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexRuleProjectRole ON RuleProject(ruleId)";
        database << "CREATE INDEX IndexRuleProjectProject ON RuleProject(projectId)";

        // Календарь -----------------------------------------------------------
        database << "CREATE TABLE UserDay"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    ", userId INTEGER"
                    // Поля с данными
                    ", date DATE"
                    ", isWorkDay BOOLEAN"
                    ", beginWorkTime TIME"
                    ", endWorkTime TIME"
                    ", breakDuration TIME"
                    ", description VARCHAR"
                    // Отношения
                    ", FOREIGN KEY(userId) REFERENCES User(id) ON DELETE CASCADE"
                    ");";
        database << "CREATE INDEX IndexUserDayUser ON UserDay(userId)";

        database << "CREATE TABLE StandardDay"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    // Поля с данными
                    ", weekDayNumber INTEGER"
                    ", weekOrder INTEGER"
                    ", isWorkDay BOOLEAN"
                    ", beginWorkTime TIME"
                    ", endWorkTime TIME"
                    ", breakDuration TIME"
                    ");";

        database << "CREATE TABLE SpecialDay"
                    // Идентификаторы
                    "( id INTEGER PRIMARY KEY"
                    // Поля с данными
                    ", date DATE"
                    ", isWorkDay BOOLEAN"
                    ", beginWorkTime TIME"
                    ", endWorkTime TIME"
                    ", breakDuration TIME"
                    ");";
    }

    virtual void down(sqlite::database& database) override
    {
        // Календарь -----------------------------------------------------------
        database << "DROP TABLE SpecialDay;";

        database << "DROP TABLE StandardDay;";

        database << "DROP INDEX IndexUserDayUser;";
        database << "DROP TABLE UserDay;";

        // Права и правила -----------------------------------------------------
        database << "DROP INDEX IndexRuleProjectProject;";
        database << "DROP INDEX IndexRuleProjectRole;";
        database << "DROP TABLE RuleProject;";

        database << "DROP INDEX IndexRuleItemTypeItemType;";
        database << "DROP INDEX IndexRuleItemTypeRole;";
        database << "DROP TABLE RuleItemType;";

        database << "DROP INDEX IndexRuleStateState;";
        database << "DROP INDEX IndexRuleStateRole;";
        database << "DROP TABLE RuleState;";

        database << "DROP INDEX IndexRuleRole;";
        database << "DROP TABLE Rule;";

        // Комментарий ---------------------------------------------------------
        database << "DROP INDEX IndexCommentDocumentVersionDocumentVersion;";
        database << "DROP INDEX IndexCommentDocumentVersionComment;";
        database << "DROP TABLE CommentDocumentVersion;";

        database << "DROP INDEX IndexCommentItem;";
        database << "DROP INDEX IndexCommentUser;";
        database << "DROP TABLE Comment;";

        // Объект предметной области -------------------------------------------
        database << "DROP INDEX IndexItemDocumentVersionDocumentVersion;";
        database << "DROP INDEX IndexItemDocumentVersionItem;";
        database << "DROP TABLE ItemDocumentVersion;";

        database << "DROP INDEX IndexItemUserStateState;";
        database << "DROP INDEX IndexItemUserStateUser;";
        database << "DROP INDEX IndexItemUserStateItem;";
        database << "DROP TABLE ItemUserState;";

        database << "DROP INDEX IndexItemHistoryUser;";
        database << "DROP INDEX IndexItemHistoryItem;";
        database << "DROP TABLE ItemHistory;";

        database << "DROP INDEX IndexItemPlanUser;";
        database << "DROP INDEX IndexItemPlanItem;";
        database << "DROP TABLE ItemPlan;";

        database << "DROP INDEX IndexItemLinkDestinaionItem;";
        database << "DROP INDEX IndexItemLinkSourceItem;";
        database << "DROP INDEX IndexItemLinkLinkType;";
        database << "DROP TABLE ItemLink;";

        database << "DROP INDEX IndexLinkTypeDestinaionItemType;";
        database << "DROP INDEX IndexLinkTypeSourceItemType;";
        database << "DROP TABLE LinkType;";

        database << "DROP INDEX IndexItemFieldFieldType;";
        database << "DROP INDEX IndexItemFieldItem;";
        database << "DROP TABLE ItemField;";

        database << "DROP INDEX IndexFieldTypePossibleValueFieldType;";
        database << "DROP TABLE FieldTypePossibleValue;";

        database << "DROP INDEX IndexFieldTypeItemType;";
        database << "DROP TABLE FieldType;";

        database << "DROP INDEX IndexItemPhase;";
        database << "DROP INDEX IndexItemState;";
        database << "DROP INDEX IndexItemParent;";
        database << "DROP INDEX IndexItemItemType;";
        database << "DROP TABLE Item;";

        database << "DROP INDEX IndexItemTypeState;";
        database << "DROP INDEX IndexItemTypeWorkflow;";
        database << "DROP TABLE ItemType;";

        // Сообщение -----------------------------------------------------------
        database << "DROP INDEX IndexTeamMessageTeam;";
        database << "DROP INDEX IndexTeamMessageSenderUser;";
        database << "DROP TABLE TeamMessage;";

        database << "DROP INDEX IndexPrivateMessageReceiverUser;";
        database << "DROP INDEX IndexPrivateMessageSenderUser;";
        database << "DROP TABLE PrivateMessage;";

        // Документ ------------------------------------------------------------
        database << "DROP TABLE Document;";

        database << "DROP TABLE DocumentVersion;";
        database << "DROP INDEX IndexDocumentVersionDocument;";

        // Пользователь --------------------------------------------------------
        database << "DROP INDEX IndexProjectTeamTeam;";
        database << "DROP INDEX IndexProjectTeamProject;";
        database << "DROP TABLE ProjectTeam;";

        database << "DROP INDEX IndexRoleMenuItemRole;";
        database << "DROP TABLE RoleMenuItem;";

        database << "DROP INDEX IndexUserTeamRoleRole;";
        database << "DROP INDEX IndexUserTeamRoleTeam;";
        database << "DROP INDEX IndexUserTeamRoleUser;";
        database << "DROP TABLE UserTeamRole;";

        database << "DROP TABLE Role;";
        database << "DROP TABLE Team;";
        database << "DROP TABLE User;";

        // Доска ---------------------------------------------------------------
        database << "DROP INDEX IndexBoardColumnState;";
        database << "DROP INDEX IndexBoardColumnBoard;";
        database << "DROP TABLE BoardColumn;";

        database << "DROP INDEX IndexBoardPhase;";
        database << "DROP INDEX IndexBoardProject;";
        database << "DROP INDEX IndexBoardWorkflow;";
        database << "DROP TABLE Board;";

        // Проект --------------------------------------------------------------
        database << "DROP INDEX IndexPhaseProject;";
        database << "DROP TABLE Phase;";

        database << "DROP INDEX IndexProjectParent;";
        database << "DROP TABLE Project;";

        // Рабочий процесс -----------------------------------------------------
        database << "DROP INDEX IndexEdgeEndState;";
        database << "DROP INDEX IndexEdgeBeginState;";
        database << "DROP TABLE Edge;";

        database << "DROP INDEX IndexStateWorkflow;";
        database << "DROP TABLE State;";

        database << "DROP TABLE Workflow;";
    }

    virtual unsigned version() override
    {
        return 1;
    }
};

} // namespace Database

#endif // DATABASE_MIGRATION_0_H
